#include "header.h"
 // constructor
StartUpConfigurationFile::StartUpConfigurationFile()
{  
	//cout<<"INSIDE THIS"<<endl;
	Port=0;
	HostName = NULL;
	Location=0;
	HomeDir="";
	LogFilename="servant.log";
	AutoShutdown=900;
	TTL = 30;
	MsgLifetime=30;
	GetMsgLifetime=300;
	InitNeighbors=3;
	JoinTimeout=15;
	KeepAliveTimeout=60;
	MinNeighbors=2;
	NoCheck=0;
	CacheProb=0.1;
	StoreProb=0.1;
	NeighborStoreProb=0.2;
	CacheSize=500;
	Retry=30;
	nodeID = NULL;
	nodeInstanceID = NULL;
}

// defining the start up functions
uint16_t StartUpConfigurationFile::getPort()
{
	return Port;
}

char* StartUpConfigurationFile::getHostName()
{
	return HostName;
}
 
unsigned long int StartUpConfigurationFile::getLocation()
{
	return Location;
}

string StartUpConfigurationFile::getHomeDir()
{
	return HomeDir;
}

string StartUpConfigurationFile::getLogFilename()
{
	return LogFilename;
}

uint32_t StartUpConfigurationFile::getAutoShutdown()
{
	return AutoShutdown;
}

uint8_t StartUpConfigurationFile::getTTL()
{
	return TTL;
}

uint32_t StartUpConfigurationFile::getMsgLifetime()
{
	return MsgLifetime;
}

uint32_t StartUpConfigurationFile::getGetMsgLifetime()
{
	return GetMsgLifetime;
}

uint32_t StartUpConfigurationFile::getInitNeighbors()
{
	return InitNeighbors;
}

uint32_t StartUpConfigurationFile::getJoinTimeout()
{
	return JoinTimeout;
}

uint32_t StartUpConfigurationFile::getKeepAliveTimeout()
{
	return KeepAliveTimeout;
}

uint32_t StartUpConfigurationFile::getMinNeighbors()
{
	return MinNeighbors;
}

bool StartUpConfigurationFile::getNoCheck()
{
	return NoCheck;
}

float StartUpConfigurationFile::getCacheProb()
{
	return CacheProb;
}

float StartUpConfigurationFile::getStoreProb()
{
	return StoreProb;
}

float StartUpConfigurationFile::getNeighborStoreProb()
{
	return NeighborStoreProb;
}

uint32_t StartUpConfigurationFile::getCacheSize()
{
	return CacheSize;
}

uint32_t StartUpConfigurationFile::getRetry()
{
	return Retry;
}

multimap<string,uint16_t> StartUpConfigurationFile::getBeaconList()
{
	return beaconList;
}
multimap<string,int> StartUpConfigurationFile::getNeighborList()
{
	return neighborList;
}
list<int> StartUpConfigurationFile::getRemoveConnectionList()
{
	return removeConnectionList;
}
map<string, int> StartUpConfigurationFile::getUoidMessageLifeTime()
{
	return uoidMessageLifeTime;
}
map<string, int> StartUpConfigurationFile::getUoidSocketDescripter()
{
	return uoidSocketDescripter;
}

char * StartUpConfigurationFile::getNodeID()
{
	return nodeID;
}
char * StartUpConfigurationFile::getNodeInstanceID()
{
	return nodeInstanceID;
}
string StartUpConfigurationFile::getUOIDStatus()
{
	return senderStatusUoid;
}





// set functions
void StartUpConfigurationFile::setPort(uint16_t port)
{
	this->Port=port;
}
void StartUpConfigurationFile::setHostName(char* HostName)
{
	this->HostName=HostName;
}
void StartUpConfigurationFile::setNodeID(char* hostname, uint16_t port)
{
	char *nodeID = (char *)malloc(50*sizeof(char));
	sprintf(nodeID, "%s_%u", hostname, port);
	this->nodeID = nodeID;
}
void StartUpConfigurationFile::setNodeInstanceID(char *nodeID)
{
	char *nodeInstanceID = (char *)malloc(100*sizeof(char));
	time_t currentTime;
	currentTime = time(NULL);
	sprintf(nodeInstanceID, "%s_%u", nodeID, (uint32_t)currentTime);
	this->nodeInstanceID = nodeInstanceID;
}
void StartUpConfigurationFile::setNeighborList(multimap<string, int> neighborList)
{
	this->neighborList = neighborList;
}
void StartUpConfigurationFile::setRemoveConnectionList(list<int> removeConnectionList)
{
	this->removeConnectionList = removeConnectionList;
}
void StartUpConfigurationFile::setUoidMessageLifeTime(map<string, int>uoidMessageLifeTime)
{
	this->uoidMessageLifeTime = uoidMessageLifeTime;
}
void StartUpConfigurationFile::setUoidSocketDescripter(map<string, int>uoidSocketDescripter)
{
	this->uoidSocketDescripter = uoidSocketDescripter;
}
void StartUpConfigurationFile::setUOIDStatus(string senderStatusUoid)
{
	this->senderStatusUoid = senderStatusUoid;
}


void StartUpConfigurationFile::VerifyIfHomeDirectoryExists()				// check if home directory is present or not.
{
	bool FileNotCreated= false;
	int check=0;

	// want to check the existence of the directory in the home folder
	struct stat st;
	if(stat(this->getHomeDir().c_str(),&st) == 0)
	//if(stat("ee450",&st) == 0)
	{
		if (S_ISDIR(st.st_mode))						//http://linux.die.net/man/2/stat				//http://www.velocityreviews.com/forums/t317606-readdir-and-s_isdir-stat-st_mode-question-ot.html
		{
			//printf("The home directory is present\n");
		}
		else
		{
			//printf("The home directory is not present\n");
			exit(1);
		}
	}		
	else
	{
		//printf("The home directory is not present\n");
		exit(1);
	}

	// check the existence of the files folder in the home dir
	struct stat st1;
	if(stat((this->getHomeDir()+"/files").c_str(),&st1) == 0)
	//if(stat("ee450/files",&st1) == 0)
	{
		if (S_ISDIR(st1.st_mode))						
		{
			//printf("The file directory is present\n");
		}
		else
		{
			//printf("The file directory is not present\n");
			FileNotCreated = true;
		}
	}
	else
	{
		//printf("The file directory is not present\n");
		FileNotCreated = true;
	}

	if (FileNotCreated)
	{
		// create the file folder under the home directory
		check=mkdir((this->getHomeDir()+"/files").c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);   //http://www.dreamincode.net/forums/topic/27741-create-directory-using-c/
		//printf("Check for create make is %d\n", check);	
	}
}

int StartUpConfigurationFile::verifyIfInitFileIsPresent()
{
	//check if the init file is present in the list or not
	struct stat st;
	//string filename = "/init_neighbor_list";
	//const char *finalpath = (const char *)(this->getHomeDir() + filename).c_str();
	if(stat((this->getHomeDir()+"/init_neighbor_list").c_str(),&st) == 0)
	{
		//printf("The init_neighbour_list file is present\n");
		return 1;
	}
	else
	{
		//printf("The init_neighbour_list file is not present\n");
		return 0;
	}
}


// Code  derived from http://avdongre.wordpress.com/2011/08/11/ini-file-parser-c/ ***/
// parse the config file
void StartUpConfigurationFile::ParseStartupConfigFile(string startUpFile)
{
	IniParser myParser;
	try
	{
		myParser.Load(startUpFile);
	
		//first 3 important parameters of init section

		//1. Port
		if((myParser.QueryKeyValue<uint16_t>("init","Port",Port))==true)
		{
			//cout<<"\nPort value is : "<<Port;
			setPort(Port);
		}
	
		else
		{
			cout<<"Port key/vlue pair not found";
			exit(1);
		}

		//2.Location
		if((myParser.QueryKeyValue<unsigned long int>("init","Location",Location))==false)
		{
			cout<<"Location key not found";
			exit(1);
		}

		//3.homedir
		if((myParser.QueryKeyValue<string>("init","HomeDir",HomeDir))==false)
		{
			cout<<"Homedir key not found";
			exit(1);
		}
	
		//fetching all the init parameters from the file
		myParser.QueryKeyValue<string>("init","LogFilename",LogFilename);
		myParser.QueryKeyValue<uint32_t>("init","AutoShutdown",AutoShutdown);
		myParser.QueryKeyValue<uint8_t>("init","TTL",TTL);
		myParser.QueryKeyValue<uint32_t>("init","MsgLifetime",MsgLifetime);
		myParser.QueryKeyValue<uint32_t>("init","GetMsgLifetime",GetMsgLifetime);
		myParser.QueryKeyValue<uint32_t>("init","InitNeighbors",InitNeighbors);
		myParser.QueryKeyValue<uint32_t>("init","JoinTimeout",JoinTimeout);
		myParser.QueryKeyValue<uint32_t>("init","KeepAliveTimeout",KeepAliveTimeout);
		myParser.QueryKeyValue<uint32_t>("init","MinNeighbors",MinNeighbors);
		myParser.QueryKeyValue<bool>("init","NoCheck",NoCheck);
		myParser.QueryKeyValue<float>("init","CacheProb",CacheProb);
		myParser.QueryKeyValue<float>("init","StoreProb",StoreProb);
		myParser.QueryKeyValue<float>("init","NeighborStoreProb",NeighborStoreProb);
		myParser.QueryKeyValue<uint32_t>("init","CacheSize",CacheSize);
		myParser.QueryKeyValue<uint32_t>("beacons","Retry",Retry);

		//fetching the beacons value
		int position=0;
		std::vector<std::string> myBeacons;
		myBeacons=myParser.getkeysForBeacon("beacons");
	
		//printf("Beacon Size = %d\n",myBeacons.size());
	
		for(unsigned int i=0;i < myBeacons.size();i++)
		{
			if ((position = myBeacons.at(i).find(':'))>0)
			{	
				string myhostname;
				string myport;
				myhostname = myBeacons.at(i).substr(0,position);
				myport = myBeacons.at(i).substr(position+1); // it will take from position+1 to n
				//cout<<"\nHostname :"<<myhostname;
			
				istringstream inputPort(myport);
				uint16_t myport1;
				inputPort >> myport1;
			
				//cout<<"\nPort :"<<myport1;
				beaconList.insert (std::pair<string,uint16_t>(myhostname,myport1));

			}
		}

		//printf("\n The size of Beacon list is : %d\n",beaconList.size());

		/*multimap<string,uint16_t>::iterator ii;															
		//ii = node.getBeaconList().find("nunki.usc.edu");
		//printf(" FInd %hu\n",(*ii).second);
		for( ii=beaconList.begin(); ii!=beaconList.end(); ii++)
		{       
			// compare the hostname and the port values
			//printf("Host Namex = %s\n",(*ii).first.c_str());
			printf("Portx ---- = %hu\n",(*ii).second);
		}*/
		

	} // end of try

	catch(IniParseException &myexception)
	{
		cout<<"Error in Ini parsing"<<endl; 
		exit(1);
	}
}

